package com.zytech.zspider.engine;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.zytech.modules.script.ScriptResult;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author siuming
 */
final class SpiderEngineHelper {

    /**
     * @param scriptResult
     * @return
     */
    static String[] castScriptResultToStringArray(ScriptResult scriptResult) {
        Object[] values = (Object[]) scriptResult.getValue();
        String[] strvals = new String[values.length];
        for (int i = 0; i < values.length; i++) {
            strvals[i] = values[i].toString();
        }
        return strvals;
    }

    /**
     * @param scriptResult
     * @return
     */
    static Iterable<String> castScriptResultToStringIterable(ScriptResult scriptResult) {
        Iterable<Object> values = (Iterable<Object>) scriptResult.getValue();
        return Iterables.transform(values, new Function<Object, String>() {
                    @Override
                    public String apply(Object input) {
                        return input.toString();
                    }
                }
        );
    }

    /**
     * @param candidates
     * @param merge
     * @return
     */
    static Set<Map<String, String>> cartesianProductParams(Map<String, Set<String>> candidates,
                                                           Map<String, String> merge) {

        List<Set<String>> nameValues = Lists.newArrayList();
        Map<Integer, String> nameIndexes = Maps.newHashMap();

        Iterator<Map.Entry<String, Set<String>>> it = candidates.entrySet().iterator();
        for (int i = 0; it.hasNext(); i++) {
            Map.Entry<String, Set<String>> entry = it.next();
            nameValues.add(i, entry.getValue());
            nameIndexes.put(i, entry.getKey());
        }

        Set<List<String>> cartesian = Sets.cartesianProduct(nameValues);
        Set<Map<String, String>> results = Sets.newHashSet();
        for (List<String> vals : cartesian) {
            Map<String, String> result = Maps.newHashMap();
            for (int i = 0; i < vals.size(); i++) {
                result.put(nameIndexes.get(i), vals.get(i));
            }

            result.putAll(merge);
            results.add(result);
        }
        return results;
    }
}
